package com.iflytek.jzcpx.procuracy.card.common.enums;


import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.qsyjs;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.qss;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.bqsjds;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.pjs;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.tqpzdbs;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.pzdbjds;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.bpzdbjds;
import static com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum.unknown;

import java.util.Collection;
import java.util.function.BiFunction;
import java.util.function.Function;

import com.google.common.collect.Lists;
import com.iflytek.jzcpx.procuracy.card.component.ElleFieldExtractFunctionFactory;
import com.iflytek.jzcpx.procuracy.card.component.FieldConvertors;
import com.iflytek.jzcpx.procuracy.card.config.ZdbmConfig;
import com.iflytek.jzcpx.procuracy.card.entity.CardFormField;
import com.iflytek.jzcpx.procuracy.card.pojo.ElleResultData;
import com.iflytek.jzcpx.procuracy.tools.elle.ElleTextTypeEnum;

import org.apache.commons.lang3.StringUtils;

/**
 * 嫌疑人表单字段枚举
 * <p>
 * 成员说明：<p>
 * CSRQ("出生日期", ElleResultData.Label::getBirthday, FieldConvertors.dateConvert("yyyy-MM-dd 00:00:00"))
 * <ul>
 *     <li>CSRQ ：赛威讯传递的表单中的json字段名称</li>
 *     <li>出生日期 ：标识字段类别，从而获取该类别下的字段编码值</li>
 *     <li>ElleResultData.Label::getBirthday ：函数式编程，用于获取该表单字段对应的elle引擎结果中的字段,
 *     使用方法参考FillAcceptFormHelper的fillXyrField()方法 </li>
 *     <li>FieldConvertors.dateConvert("yyyy-MM-dd 00:00:00") ：函数式编程，用于将elle引擎结果的字段
 *     转成该案卡表单字段要求的格式，使用方法参考FillAcceptFormHelper的fillFieldInAccept()方法</li>
 * </ul>
 * 当引擎能够抽取新的字段时，只需要增加一个枚举项就可以了，完全不用改service层逻辑
 *
 * @author <a href=mailto:ktyi@iflytek.com>伊开堂</a>
 * @date 2019-08-29 17:22
 */
public enum XYRFieldNameEnum {
    /** 姓名 当是单位犯罪时需要取OrgName作为XM*/
    XM("姓名", ElleResultData.Label::getSuspectName, 60 ,ElleResultData.Label::getOrgName, Lists.newArrayList(qsyjs,tqpzdbs,qss,pjs,pzdbjds,bpzdbjds,bqsjds)),

    /** 性别 */
    XB("性别", ElleResultData.Label::getGender, 300, Lists.newArrayList(qsyjs,tqpzdbs),"性别"),

    /** 出生日期 */
    CSRQ("出生日期", ElleResultData.Label::getBirthday, Lists.newArrayList(qsyjs,tqpzdbs), FieldConvertors.dateContactConvert(" 00:00:00")),

    /** 证件类型 */
    ZJLX("证件类型", ElleResultData.Label::getCertificates, 300, Lists.newArrayList(qsyjs,tqpzdbs),"证件类型"),

    /** 证件号码 */
    ZJHM("证件号码", ElleResultData.Label::getCertificatesId, Lists.newArrayList(qsyjs,tqpzdbs)),

    /** 民族 */
    MZ("民族", ElleResultData.Label::getEthnicity, 300,Lists.newArrayList(qsyjs,tqpzdbs),"民族"),

    /** 国籍 */
    GJ("国籍", ElleResultData.Label::getNationality, 300,Lists.newArrayList(qsyjs,tqpzdbs),"国籍"),

    /** 户籍所在地 */
    HJSZD("户籍所在地", ElleResultData.Label::getHouseholdRegisterAddress, 300,Lists.newArrayList(qsyjs,tqpzdbs),"地区代码"),

    /** 住所地详细地址 */
    ZSDXXDZ("住所地详细地址", ElleResultData.Label::getDetailedAddress, 900,Lists.newArrayList(qsyjs,tqpzdbs)),

    /** 工作单位/所在学校 */
    GZDW("工作单位", ElleResultData.Label::getWorkplace, 900,Lists.newArrayList(qsyjs,tqpzdbs)),

    /** 单位/学校所在地 */
    //GZDWSZD("单位/学校所在地", ElleResultData.Label::getWorkplaceAddress, 900,Lists.newArrayList(qsyjs,tqpzdbs)),

    /** 受教育状况 */
    SJYZK("受教育状况", ElleResultData.Label::getEducation, 300,Lists.newArrayList(qsyjs,tqpzdbs),"受教育状况"),

    /** 政治面貌 */
    ZZMM("政治面貌", ElleResultData.Label::getPoliticalStatus, 300,Lists.newArrayList(qsyjs,tqpzdbs),"政治面貌"),

    /** 主要作案地 */
    ZYZAD("主要作案地", ElleResultData.Label::getCrimePlace, 300,Lists.newArrayList(qsyjs,tqpzdbs),"地区代码"),

    /** 住所地 */
    ZSD("住所地", ElleResultData.Label::getAddress, 300,ElleResultData.Label::getOrgAddress,Lists.newArrayList(qsyjs,tqpzdbs),"地区代码"),

    /** 职级 */
    ZJ("职级", ElleResultData.Label::getRank, 300,Lists.newArrayList(qsyjs,tqpzdbs),"职级"),

    /** 职务 */
    ZW("职务", ElleResultData.Label::getPost, 300,Lists.newArrayList(qsyjs,tqpzdbs),"职务"),

    /** 职业 */
    ZY("职业", ElleResultData.Label::getOccupation, 300,Lists.newArrayList(qsyjs,tqpzdbs),"职业"),

    /** 身份 */
    SF("身份", ElleResultData.Label::getIdentity, 300 , ElleResultData.Label::getOrgNature,Lists.newArrayList(qsyjs,tqpzdbs),"身份"),

    /** 审结处理结果 */
    SJCLJG("审结处理结果", ElleResultData.Label::getArrestConcludedResults, 300,Lists.newArrayList(pzdbjds,bpzdbjds),"审查逮捕结论"),
    
    /** 审结罪名 */
    SDAY("审结罪名", ElleResultData.Label::getConcludedCharges, 300,Lists.newArrayList(qss,bpzdbjds,pzdbjds),"案由"),
    
    /** 审结其他罪名(引擎无反馈字段及结果，可从“审结罪名”字段取值) */
    SDQTAY("审结其他罪名", ElleResultData.Label::getOtherConcludedCharges, 300,Lists.newArrayList(qss,bpzdbjds,pzdbjds),"案由"),
    

    /** 检察机关是否适用认罪认罚 */
    //JCJGSFSYRZRF("检察机关是否适用认罪认罚", ElleResultData.Label::getProcuratorateApplyingGuiltyPlea, FieldConvertors.whetherConvert(), Lists.newArrayList(qss)),
    JCJGSFSYRZRF("检察机关是否适用认罪认罚",true,"N",ElleResultData.Label::getProcuratorateApplyingGuiltyPlea,FieldConvertors.whetherConvert(), Lists.newArrayList(qss,bqsjds)),

    /** 是否委托辩护人(引擎无反馈字段及结果) */
    // SFWTBHR("是否委托辩护人", ElleResultData.Label::getAdvocateByMandate, 1),
    
    /** 听取辩护人/值班律师意见日期(引擎无反馈字段及结果), T_TYYW_XJ_XBS_XYR表 */
    ZDTQBHRDYJRQ("听取辩护人意见日期", ElleResultData.Label::getDateOfHearing, FieldConvertors.dateContactConvert(" 00:00:00")),
    /** 听取辩护人/值班律师意见日期(引擎无反馈字段及结果), T_TYYW_XJ_YSGS_XYR表 */
    TQBHRYJRQ("听取辩护人/值班律师意见日期", ElleResultData.Label::getDateOfHearing, FieldConvertors.dateContactConvert(" 00:00:00")),

    /** 公开审查时间(引擎无反馈字段及结果) */
    // _2swx无对应字段("公开审查时间", ElleResultData.Label::getOpenCensorshipTime, ""),
    
    /** 提起公诉日期(引擎无反馈字段及结果，可从“移送法院日期”字段取值) */ //公诉类案件
    TQGSRQ("提起公诉日期", ElleResultData.Label::getProsecutionDate, FieldConvertors.dateContactConvert(" 00:00:00")),
    
    /** 审查认定的法定情节(引擎无反馈字段及结果) */    // 公诉案件 代码
    // FDLXQJ("审查认定的法定情节", ElleResultData.Label::getLegalPlotOfReview, 3000),
    
    /** 一审判决罪名 */      // 公诉案件 是 9003:法定刑 还是 9001:犯罪情节
    YSPJZM("一审判决罪名", ElleResultData.Label::getChargeOfFI, 300, Lists.newArrayList(pjs),"案由"),

    /** 一审判决其他罪名(引擎无反馈字段及结果，可从“一审判决罪名”字段取值) */  // 公诉案件
    YSPJQTZM("一审判决其他罪名", ElleResultData.Label::getOtherChargeOfFI, 300, Lists.newArrayList(pjs),"案由"),

    /** 一审宣告刑（主刑） */    // 公诉案件
    YSXGX("一审宣告刑（主刑）", ElleResultData.Label::getPrincipalPenaltyOfFI, 300, Lists.newArrayList(pjs),"新刑罚"),

    /** 一审宣告刑刑期 */  // 公诉案件
    YSXGXXQ("一审宣告刑刑期", ElleResultData.Label::getPrisonTermOfFI, 300, Lists.newArrayList(pjs),FieldConvertors.prisonTermOfFIAfterConvert()),
    
    /** 一审缓刑考验期 */  // 公诉案件
    YSHXKYQ("一审缓刑考验期", ElleResultData.Label::getProbationTermOfFI, 300, Lists.newArrayList(pjs),FieldConvertors.prisonTermOfFIAfterConvert()),
    
    /** 一审附加刑类型 */  // 公诉案件 代码
    YSFJXQK("一审附加刑类型", ElleResultData.Label::getAccessoryPenaltyOfFI, 3000, Lists.newArrayList(pjs),"一审附加刑情况代码"),

    /** 一审附加刑具体情况 */    // 公诉案件
    YSFJXJTQK("一审附加刑具体情况", ElleResultData.Label::getAccessoryPenaltyContentOfFI, 300, Lists.newArrayList(pjs)),
    
    /** 一审罚金数额（万元） */   // 公诉案件, NUMBER(14, 6) 类型
    YSFJSE_NUM("一审罚金数额（万元）", ElleResultData.Label::getFineOfFI, Lists.newArrayList(pjs)),
    
    /** 被告人裁判情况-一审裁判情况-裁判认定法定情节 */
    //PJFDLXQJS("裁判认定法定情", ElleResultData.Label::getLegalPlotOfJudgment, 300, Lists.newArrayList(pjs),"法定量刑情节"),
    PJFDLXQJ("裁判认定法定情", ElleResultData.Label::getLegalPlotOfJudgment, 300, Lists.newArrayList(pjs),"法定量刑情节"),
    
    /** 强制措施决定日期 */
    // _9swx无对应字段("强制措施决定日期", ElleResultData.Label::getCompulsoryMeasureDate, ""),
    /**审结金额**/
    SDSE("审结数额", ElleResultData.Label::getConcludedAmount,300),
    /**移送意见**/
    YSYJ("移送意见",1,FieldConvertors.ysyjConvert(), Lists.newArrayList(qsyjs),"移送意见"),
    /**侦查机关是否建议适用认罪认罚**/
    ZCJGSFJYSYRZRF("侦(调)查机关建议是否建议适用认罪认罚",true,"N",ElleResultData.Label::getInvestigationApplyingGuiltyPlea,FieldConvertors.whetherConvert(), Lists.newArrayList(qsyjs)),
    
    /** 嫌疑人 - (不)起诉书文号 */
    BQSSWH("（不）起诉书文号",1,ElleFieldExtractFunctionFactory.buildWHFunc(), Lists.newArrayList(qss,bqsjds)),
    /**嫌疑人审结及变更情况-审结情况-审结日期 */
    SJRQ("审结日期",1,ElleFieldExtractFunctionFactory.buildSJRQFunc(), Lists.newArrayList(qss,pzdbjds,bpzdbjds)),
    /** 审结处理情况(引擎无反馈字段及结果，可从“审结情况”字段取值) */
    SJCLQK("审结处理情况", ElleResultData.Label::getConcludedSituation, Lists.newArrayList(qss),"审查起诉结论"),
    
    /** 被告人裁判情况-一审裁判情况-一审判决日期*/
    YYSPJRQ( "一审判决日期", 1,ElleFieldExtractFunctionFactory.buildYSPJRQFunc(), Lists.newArrayList(pjs)),
    /**被告人裁判情况-一审裁判情况-一审判决书文号**/
    YSPJSWH( "一审判决书文号", 1,ElleFieldExtractFunctionFactory.buildWHFunc(), Lists.newArrayList(pjs)),
    /** 嫌疑人 - (不)逮捕书文号 */
    DBSWH("（不）逮捕书文号", 1 ,ElleFieldExtractFunctionFactory.buildWHFunc(),Lists.newArrayList(pzdbjds,bpzdbjds)),
    
    //-------R版本引擎后处理新增
    CYM("曾用名",ElleResultData.Label::getNameUsedBefore,Lists.newArrayList(qsyjs,tqpzdbs)),
    CH("绰号",ElleResultData.Label::getNickName,Lists.newArrayList(qsyjs,tqpzdbs)),
    RDDB("人大代表",ElleResultData.Label::getNpcMember,Lists.newArrayList(qsyjs,tqpzdbs),"人大代表"),
    ZXWY("政协委员",ElleResultData.Label::getCppccMember,Lists.newArrayList(qsyjs,tqpzdbs),"政协委员"),
    SFNCJCZZRY("是否农村基层组织人员",true,"N",ElleResultData.Label::getRuralGrassroofsOrgPersonnel,FieldConvertors.sfncjczzryConvert(), Lists.newArrayList(qsyjs,tqpzdbs)),
    ZASJ("作案时间",ElleResultData.Label::getTime, Lists.newArrayList(qsyjs,tqpzdbs)),
    QTGZSF("其他关注身份",ElleResultData.Label::getOtherIdentity,Lists.newArrayList(qsyjs,tqpzdbs),"其他关注身份"),
    
    XSCF("刑事处罚",ElleResultData.Label::getCriminalRecord, Lists.newArrayList(unknown)),
    LJ("劳教",ElleResultData.Label::getIndoctrinationLabour, Lists.newArrayList(unknown)),
    //QK("前科",true,FieldConvertors.qkConvert(), Lists.newArrayList(qsyjs,tqpzdbs)),
    QK("前科",ElleResultData.Label::getQk, Lists.newArrayList(qsyjs,tqpzdbs),"前科"),
    
    DWMC("单位名称",ElleResultData.Label::getOrgName,Lists.newArrayList(qsyjs)),
    /**是否为单位 若“单位名称”标签有值，则“是否为单位”取值“是”，反之则为“否”。**/
    SFWDW("是否为单位",true,FieldConvertors.sfwdwConvert(),Lists.newArrayList(qsyjs)),
    
    DWXZ("单位性质",ElleResultData.Label::getOrgNature,Lists.newArrayList(qsyjs),"身份"),
    DWSZDZ("单位所在地址",ElleResultData.Label::getOrgAddress,Lists.newArrayList(qsyjs)),
    ZZJGDM("组织机构代码",ElleResultData.Label::getOrgCode),
    FDDBRXM("法定代表人姓名",ElleResultData.Label::getLegalRepseName,Lists.newArrayList(qsyjs)),
    FDDBRZW("法定代表人职务",ElleResultData.Label::getLegalRepsepost,Lists.newArrayList(qsyjs)),
    SSDBRXM("诉讼代表人姓名",ElleResultData.Label::getLitigantRepreseName,Lists.newArrayList(qsyjs)),
    SSDBRZW("诉讼代表人职务",ElleResultData.Label::getLitigantRepresePost,Lists.newArrayList(qsyjs)),
    //SSDBRLXFS("诉讼代表人联系方式",ElleResultData.Label::getLitigantRepreseTel),
    
    //需要映射字段
    /** 犯罪嫌疑人情况-涉案情况-移诉案由 */
    YS("移诉案由",ElleResultData.Label::getLitigationCharges,Lists.newArrayList(qsyjs,tqpzdbs),"案由"),
    /** 犯罪嫌疑人情况-涉案情况-移诉其他案由 */
    YSQT("移诉其他案由",ElleResultData.Label::getOtherLitigationCharges,Lists.newArrayList(qsyjs,tqpzdbs),"案由"),
    /** 案件 - 移送意见 */
    //YSYJ("移送意见"),
    ZASNL("作案时年龄",true,FieldConvertors.zasnlConvertNew(),Lists.newArrayList(qsyjs,tqpzdbs)),
    GZDWSZD("工作单位/学校所在地",ElleResultData.Label::getWorkplaceArea,Lists.newArrayList(qsyjs,tqpzdbs),"地区代码"),
    
    SJSQZCSZT("审结时强制措施状态", ElleResultData.Label::getSJSQZCSZT, 300,Lists.newArrayList(qss),"强制措施"),
    ;

    /** 字段名称 */
    private String mc;
    
    /** 默认值 */
    private String defaultValue;
    
    /**是否有映射函数**/
    private boolean hasMapFunc=false;
    
    /** 用来获取引擎映射字段值的函数 */
    private Function<ElleResultData.Label, String> mappingFunc;
    
    /**是否有案件的映射函数**/
    private int hasCaseMapFunc=0;

	public int getHasCaseMapFunc() {
		return hasCaseMapFunc;
	}

	/** 用来获取引擎映射字段值的函数 */
    private Function<ElleResultData, ElleResultData.Item> caseMappingFunc;
    
    /** 另外一种elle取值方法  通过案件信息转换**/
    private BiFunction<ElleResultData.Label,ElleResultData,String> caseElleFieldExtractor;
    
    /** 字段来自哪种文书, 只有当文书是这种类型时, 这个字段才需要回填 */
    private Collection<ElleTextTypeEnum> supportElleTextType;

    public Collection<ElleTextTypeEnum> getSupportElleTextType() {
		return supportElleTextType;
	}

	public Function<ElleResultData, ElleResultData.Item> getCaseMappingFunc() {
		return caseMappingFunc;
	}

	public Function<ElleResultData.Label, String> getMappingFunc() {
		return mappingFunc;
	}

	public boolean isHasMapFunc() {
		return hasMapFunc;
	}

	/** 用来抽取elle引擎字段值的函数 */
    private Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor;
    
    /** 当用原字段抽取值为空值时候 用来elle其他字段作为这个值的填充函数  */
    private Function<ElleResultData.Label, ElleResultData.Item[]> isNullElleFieldExtractor;

    public Function<ElleResultData.Label, ElleResultData.Item[]> getIsNullElleFieldExtractor() {
		return isNullElleFieldExtractor;
	}

	/** 字段文本值格式转换方法 */
    private Function<String, String> convertFunc ;

    /** 类别名称, 如果为空则不需要解析字段编码值 */
    private String lbmc;

    /** 字段文本值长度限制, 需要对照赛威讯案卡数据结构赋值 */
    private int zdwbzLimitSize = 300;
    
    XYRFieldNameEnum(String mc,boolean hasMapFunc,BiFunction<ElleResultData.Label,ElleResultData,String> caseElleFieldExtractor,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.caseElleFieldExtractor=caseElleFieldExtractor;
        this.hasMapFunc=hasMapFunc;
        this.supportElleTextType=supportElleTextType;
    }
    
    XYRFieldNameEnum(String mc,int hasCaseMapFunc,Function<ElleResultData, ElleResultData.Item> caseMappingFunc,Collection<ElleTextTypeEnum> supportElleTextType
    		,String lbmc) {
        this.mc = mc;
        this.caseMappingFunc=caseMappingFunc;
        this.hasCaseMapFunc=hasCaseMapFunc;
        this.supportElleTextType=supportElleTextType;
        this.lbmc=lbmc;
    }
    
    XYRFieldNameEnum(String mc,int hasCaseMapFunc,Function<ElleResultData, ElleResultData.Item> caseMappingFunc,Collection<ElleTextTypeEnum> supportElleTextType
    		) {
        this.mc = mc;
        this.caseMappingFunc=caseMappingFunc;
        this.hasCaseMapFunc=hasCaseMapFunc;
        this.supportElleTextType=supportElleTextType;
    }
    
    XYRFieldNameEnum(String mc,int hasCaseMapFunc,Function<ElleResultData, ElleResultData.Item> caseMappingFunc) {
        this.mc = mc;
        this.caseMappingFunc=caseMappingFunc;
        this.hasCaseMapFunc=hasCaseMapFunc;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,int zdwbzLimitSize,
    		Function<ElleResultData.Label, ElleResultData.Item[]> isNullElleFieldExtractor,Collection<ElleTextTypeEnum> supportElleTextType,String lbmc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.isNullElleFieldExtractor=isNullElleFieldExtractor;
        this.supportElleTextType=supportElleTextType;
        this.lbmc=lbmc;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,int zdwbzLimitSize,
    		Function<ElleResultData.Label, ElleResultData.Item[]> isNullElleFieldExtractor,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.isNullElleFieldExtractor=isNullElleFieldExtractor;
        this.supportElleTextType=supportElleTextType;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,int zdwbzLimitSize,
    		Function<ElleResultData.Label, ElleResultData.Item[]> isNullElleFieldExtractor) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.isNullElleFieldExtractor=isNullElleFieldExtractor;
    }
    
	XYRFieldNameEnum(String mc,boolean hasMapFunc,Function<ElleResultData.Label, String> mappingFunc,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.mappingFunc=mappingFunc;
        this.hasMapFunc=hasMapFunc;
        this.supportElleTextType=supportElleTextType;
    }
	
	XYRFieldNameEnum(String mc,Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Function<String, String> convertFunc
			,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.elleFieldExtractor=elleFieldExtractor;
        this.convertFunc=convertFunc;
        this.supportElleTextType=supportElleTextType;
    }
	
    XYRFieldNameEnum(String mc,String defaultValue,Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Function<String, String> convertFunc) {
        this.mc = mc;
        this.defaultValue=defaultValue;
        this.elleFieldExtractor=elleFieldExtractor;
        this.convertFunc=convertFunc;
    }
    
    XYRFieldNameEnum(String mc,boolean hasMapFunc,String defaultValue,Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Function<String, String> convertFunc,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.hasMapFunc=hasMapFunc;
        this.elleFieldExtractor=elleFieldExtractor;
        this.convertFunc=convertFunc;
        this.defaultValue=defaultValue;
        this.supportElleTextType=supportElleTextType;
    }
    
    XYRFieldNameEnum(String mc,boolean hasMapFunc,String defaultValue,Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Function<String, String> convertFunc) {
        this.mc = mc;
        this.hasMapFunc=hasMapFunc;
        this.elleFieldExtractor=elleFieldExtractor;
        this.convertFunc=convertFunc;
        this.defaultValue=defaultValue;
    }
    
    XYRFieldNameEnum(String mc,String defaultValue) {
        this.mc = mc;
        this.defaultValue=defaultValue;
    } 
    
    XYRFieldNameEnum(String mc) {
        this.mc = mc;
    } 
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Collection<ElleTextTypeEnum> supportElleTextType,
    		String lbmc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.supportElleTextType=supportElleTextType;
        this.lbmc=lbmc;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.supportElleTextType=supportElleTextType;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,Collection<ElleTextTypeEnum> supportElleTextType,
    		Function<String, String> convertFunc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.supportElleTextType=supportElleTextType;
        this.convertFunc=convertFunc;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
    }

    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            Function<String, String> convertFunc, int zdwbzLimitSize) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.convertFunc = convertFunc;
        this.zdwbzLimitSize = zdwbzLimitSize;
    }

    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            int zdwbzLimitSize, String lbmc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.lbmc = lbmc;
    }

    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            Function<String, String> convertFunc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.convertFunc = convertFunc;
    }

    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            int zdwbzLimitSize) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            int zdwbzLimitSize,Collection<ElleTextTypeEnum> supportElleTextType,String lbmc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.supportElleTextType=supportElleTextType;
        this.lbmc=lbmc;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            int zdwbzLimitSize,Collection<ElleTextTypeEnum> supportElleTextType) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.supportElleTextType=supportElleTextType;
    }
    
    XYRFieldNameEnum(String mc, Function<ElleResultData.Label, ElleResultData.Item[]> elleFieldExtractor,
            int zdwbzLimitSize,Collection<ElleTextTypeEnum> supportElleTextType,Function<String, String> convertFunc) {
        this.mc = mc;
        this.elleFieldExtractor = elleFieldExtractor;
        this.zdwbzLimitSize = zdwbzLimitSize;
        this.supportElleTextType=supportElleTextType;
        this.convertFunc=convertFunc;
    }

    /** 根据字段名称获取嫌疑人字段枚举 */
    public static XYRFieldNameEnum parseByZdmc(String zdmc) {
        if (StringUtils.isBlank(zdmc)) {
            return null;
        }

        for (XYRFieldNameEnum anEnum : values()) {
            if (anEnum.name().equalsIgnoreCase(zdmc)) {
                return anEnum;
            }
        }

        return null;
    }

    /** 根据已保存的字段数据解析字段编码值*/
    public static String convertZdbmzForBdjg(CardFormField field) {
        if (field == null) {
            return "";
        }

        String zdwbz = field.getZdwbz();
        String zdbmz = field.getZdbmz();
        String zdmc = field.getZdmc();
        XYRFieldNameEnum fieldNameEnum = parseByZdmc(zdmc);
        if (fieldNameEnum != null) {
            // 字段有类别名称配置, 说明字段有编码值配置, 因此需要返回字段编码值, 否则将字段文本值作为编码值返回
            return StringUtils.isNotBlank(fieldNameEnum.getLbmc()) ? zdbmz : zdwbz;
        }
        else {
            return StringUtils.isNotBlank(zdbmz) ? zdbmz : zdwbz;
        }
    }

    public String getLbmc() {
        return lbmc;
    }

    public String getMc() {
        return mc;
    }

    public Function<ElleResultData.Label, ElleResultData.Item[]> getElleFieldExtractor() {
        return elleFieldExtractor;
    }
    
    public String getDefaultValue() {
    	return defaultValue;
    }

    /** 字段文本值转换处理 */
    public String convertZdwbz(String input) {
    	if(null == convertFunc) {
    		return input;
    	}
        String zdwbz = convertFunc.apply(input);
        // 截断, 防止文本超长
        return StringUtils.substring(zdwbz, 0, zdwbzLimitSize);
    }

    /** 字段编码值转换处理, 在回填到表单结构时调用 */
    public String convertZdbmzForBdjg(String zdwbz, ZdbmConfig zdbmConfig) {
        // 解析字段编码值，如果字段没有配置编码值，则把文本值填入编码值字段
        // 如果有配置编码值，且能解析出对应编码值则填入编码值字段，否则不填
        if (StringUtils.isBlank(zdwbz) || zdbmConfig == null || StringUtils.isBlank(this.lbmc)) {
            return zdwbz;
        }

        return zdbmConfig.getZdbm(this.lbmc, zdwbz);
    }

    /** 字段编码值转换处理, 在保存字段到数据库时调用,  */
    public String convertZdbmzForStore(String zdwbz, ZdbmConfig zdbmConfig) {
        // 解析字段编码值，如果字段没有配置编码值，则把文本值填入编码值字段
        // 但为了防止字段文本值超长导致存储失败, 因此使用空字符而不是文本值保存到编码值字段
        if (StringUtils.isBlank(zdwbz) || zdbmConfig == null || StringUtils.isBlank(this.lbmc)) {
            return "";
        }

        return zdbmConfig.getZdbm(this.lbmc, zdwbz);
    }

	public BiFunction<ElleResultData.Label, ElleResultData, String> getCaseElleFieldExtractor() {
		return caseElleFieldExtractor;
	}
}

